home *** CD-ROM | disk | FTP | other *** search
/ The Arsenal Files 8 / The Arsenal Files Collection #8 (Arsenal Computer) (1996).ISO / prg_gen / euphor14.zip / WIRE.EX < prev   
Text File  |  1996-10-15  |  8KB  |  315 lines

  1.         ----------------------------
  2.         -- 3-D Wire Frame Picture --
  3.         ----------------------------
  4. -- Hit space bar to freeze/restart the picture.
  5. -- Any other key to quit.
  6.  
  7. without type_check
  8.  
  9. include graphics.e
  10. include select.e
  11.  
  12. constant GRAPHICS_MODE = 261  -- SVGA, N.B. If this fails try mode 18.
  13.  
  14. constant X = 1, Y = 2, Z = 3
  15. constant TRUE = 1
  16. constant SCREEN = 1
  17. constant ANY_MODE_WHITE = 255
  18.  
  19. type point(sequence x)
  20.     return length(x) = 3
  21. end type
  22.  
  23. type matrix(sequence x)
  24.     return length(x) = 4 and sequence(x[1])
  25. end type
  26.  
  27. type vector(sequence x)
  28.     return length(x) = 4 and atom(x[1])
  29. end type
  30.  
  31. integer axis
  32. atom sin_angle, cos_angle
  33.  
  34. function product(sequence factor)
  35. -- matrix multiply a number of 4-vectors/4x4 matrices
  36. -- only the first one could be a vector
  37.     sequence a, c
  38.     matrix b
  39.  
  40.     a = factor[1]
  41.     for f = 2 to length(factor) do
  42.     b = factor[f]
  43.     if atom(a[1]) then
  44.         -- a is a vector
  45.         c = repeat(0, 4)
  46.         for j = 1 to 4 do
  47.         c[j] = a[1] * b[1][j] +
  48.                a[2] * b[2][j] +
  49.                a[3] * b[3][j] +
  50.                a[4] * b[4][j]
  51.         end for
  52.     else
  53.         -- a is a matrix
  54.         c = repeat(repeat(0, 4), 4)
  55.         for i = 1 to 4 do
  56.         for j = 1 to 4 do
  57.             for k = 1 to 4 do
  58.             c[i][j] = c[i][j] + a[i][k] * b[k][j]
  59.             end for
  60.         end for
  61.         end for
  62.     end if
  63.     a = c
  64.     end for
  65.     return c
  66. end function
  67.  
  68. sequence vc -- video configuration
  69.  
  70. procedure display(sequence old_coords, sequence coords)
  71. -- erase the old lines, draw the new ones
  72.     for i = 1 to length(old_coords) do
  73.     draw_line(BLACK, old_coords[i][1..2])
  74.     end for
  75.     for i = 1 to length(coords) do
  76.     if vc[VC_COLOR] then
  77.         draw_line(coords[i][3], coords[i][1..2])
  78.     else
  79.         draw_line(ANY_MODE_WHITE, coords[i][1..2])
  80.     end if
  81.     end for
  82. end procedure
  83.  
  84. function view(point view_point)
  85. -- compute initial view
  86.     matrix t1, t2, t3, t4, n
  87.     atom cos_theta, sin_theta, hyp, a_b
  88.  
  89.     -- change origin
  90.     t1 = {{1, 0, 0, 0},
  91.       {0, 1, 0, 0},
  92.       {0, 0, 1, 0},
  93.       -view_point & 1}
  94.  
  95.     -- get left-handed coordinate system
  96.     t2 = {{-1, 0,  0, 0},
  97.       { 0, 0, -1, 0},
  98.       { 0, 1,  0, 0},
  99.       { 0, 0,  0, 1}}
  100.  
  101.     -- rotate so Ze points properly
  102.     hyp = sqrt(view_point[1] * view_point[1] + view_point[2] * view_point[2])
  103.     sin_theta = view_point[1] / hyp
  104.     cos_theta = view_point[2] / hyp
  105.     t3 = {{cos_theta, 0, sin_theta, 0},
  106.       {        0, 1,         0, 0},
  107.       {-sin_theta,0, cos_theta, 0},
  108.       {        0, 0,         0, 1}}
  109.  
  110.     -- rotate so Ze points at the origin (0, 0, 0)
  111.     t4 = {{1, 0, 0, 0},
  112.       {0, cos_theta, -sin_theta, 0},
  113.       {0, sin_theta, cos_theta, 0},
  114.       {0, 0, 0, 1}}
  115.  
  116.     a_b = 2
  117.  
  118.     n = {{a_b, 0, 0, 0},
  119.      {0, a_b, 0, 0},
  120.      {0, 0, 1, 0},
  121.      {0, 0, 0, 1}}
  122.  
  123.     return product({t1, t2, t3, t4, n})
  124. end function
  125.  
  126. function new_coords(sequence overall, sequence shape)
  127. -- compute the screen coordinates from the 3-D coordinates
  128.     sequence screen_coords, final
  129.     point p
  130.     atom x2, y2
  131.  
  132.     x2 = vc[VC_XPIXELS]/2
  133.     y2 = vc[VC_YPIXELS]/2
  134.     screen_coords = repeat({0, 0, 0}, length(shape))
  135.     for i = 1 to length(shape) do
  136.     for j = 1 to 2  do
  137.         p = shape[i][j]
  138.         final = product({p & 1, overall})
  139.         screen_coords[i][j] = {x2*(final[X]/final[Z]+1),
  140.                    y2*(final[Y]/final[Z]+1)}
  141.     end for
  142.     screen_coords[i][3] = shape[i][3]
  143.     end for
  144.     return screen_coords
  145. end function
  146.  
  147. function x_rotate(point p)
  148. -- compute x rotation of a point
  149.     return {p[X],
  150.         p[Y] * cos_angle + p[Z] * sin_angle,
  151.         p[Z] * cos_angle - p[Y] * sin_angle}
  152. end function
  153.  
  154. function y_rotate(point p)
  155. -- compute y rotation of a point
  156.     return {p[X] * cos_angle - p[Z] * sin_angle,
  157.         p[Y],
  158.         p[X] * sin_angle + p[Z] * cos_angle}
  159. end function
  160.  
  161. function z_rotate(point p)
  162. -- compute z rotation matrix
  163.     return {p[X] * cos_angle + p[Y] * sin_angle,
  164.         p[Y] * cos_angle - p[X] * sin_angle,
  165.         p[Z]}
  166. end function
  167.  
  168. function compute_rotate(integer axis, sequence shape)
  169. -- rotate a shape
  170.     for i = 1 to length(shape) do
  171.     for j = 1 to 2 do
  172.         if axis = X then
  173.         shape[i][j] = x_rotate(shape[i][j])
  174.         elsif axis = Y then
  175.         shape[i][j] = y_rotate(shape[i][j])
  176.         else
  177.         shape[i][j] = z_rotate(shape[i][j])
  178.         end if
  179.     end for
  180.     end for
  181.     return shape
  182. end function
  183.  
  184. -- lines a block E
  185. constant E = {
  186. {{.2, 1.1, 2}, {.2, -.5, 2}, BLUE},
  187. {{.2, -.5, 2}, {.2, -.5, -2}, YELLOW},
  188. {{.2, -.5, -2}, {.2, 1.1, -2}, GREEN},
  189. {{.2, 1.1, -2}, {.2, 1.2, -1.6}, BRIGHT_RED},
  190. {{.2, 1.2, -1.6}, {.2, 1, -1.8}, BRIGHT_RED},
  191. {{.2, 1, -1.8}, {.2, 0, -1.8}, MAGENTA},
  192. {{.2, 0, -1.8}, {.2, 0, -.1}, BRIGHT_CYAN},
  193. {{.2, 0, -.1}, {.2, .5, -.1}, BLUE},
  194. {{.2, .5, -.1}, {.2, .6, -.2}, BLUE},
  195. {{.2, .6, -.2}, {.2, .6, .2}, ANY_MODE_WHITE},
  196. {{.2, .6, .2}, {.2, .5, .1}, BLUE},
  197. {{.2, .5, .1}, {.2, 0, .1}, BRIGHT_BLUE},
  198. {{.2, 0, .1}, {.2, 0, 1.8}, BRIGHT_GREEN},
  199. {{.2, 0, 1.8}, {.2, 1, 1.8}, BRIGHT_CYAN},
  200. {{.2, 1, 1.8}, {.2, 1.2, 1.6}, BRIGHT_CYAN},
  201. {{.2, 1.2, 1.6}, {.2, 1.1, 2}, BRIGHT_RED},
  202.  
  203. -- opposite side:
  204. {{-.2, 1.1, 2}, {-.2, -.5, 2}, BLUE},
  205. {{-.2, -.5, 2}, {-.2, -.5, -2}, YELLOW},
  206. {{-.2, -.5, -2}, {-.2, 1.1, -2}, GREEN},
  207. {{-.2, 1.1, -2}, {-.2, 1.2, -1.6}, BRIGHT_RED},
  208. {{-.2, 1.2, -1.6}, {-.2, 1, -1.8}, BRIGHT_RED},
  209. {{-.2, 1, -1.8}, {-.2, 0, -1.8}, MAGENTA},
  210. {{-.2, 0, -1.8}, {-.2, 0, -.1}, BRIGHT_CYAN},
  211. {{-.2, 0, -.1}, {-.2, .5, -.1}, BLUE},
  212. {{-.2, .5, -.1}, {-.2, .6, -.2}, BLUE},
  213. {{-.2, .6, -.2}, {-.2, .6, .2}, ANY_MODE_WHITE},
  214. {{-.2, .6, .2}, {-.2, .5, .1}, BLUE},
  215. {{-.2, .5, .1}, {-.2, 0, .1}, BRIGHT_BLUE},
  216. {{-.2, 0, .1}, {-.2, 0, 1.8}, BRIGHT_GREEN},
  217. {{-.2, 0, 1.8}, {-.2, 1, 1.8}, BRIGHT_CYAN},
  218. {{-.2, 1, 1.8}, {-.2, 1.2, 1.6}, BRIGHT_CYAN},
  219. {{-.2, 1.2, 1.6}, {-.2, 1.1, 2}, BRIGHT_RED},
  220.  
  221. -- cross pieces:
  222. {{.2, 1.1, 2}, {-.2, 1.1, 2}, BLUE},
  223. {{.2, -.5, 2}, {-.2, -.5, 2}, BLUE},
  224. {{.2, -.5, -2}, {-.2, -.5, -2}, GREEN},
  225. {{.2, 1.1, -2}, {-.2, 1.1, -2}, GREEN},
  226. {{.2, 1.2, -1.6}, {-.2, 1.2, -1.6}, BRIGHT_GREEN},
  227. {{.2, .6, -.2}, {-.2, .6, -.2}, ANY_MODE_WHITE},
  228. {{.2, .6, .2}, {-.2, .6, .2}, ANY_MODE_WHITE},
  229. {{.2, 1.2, 1.6}, {-.2, 1.2, 1.6}, BRIGHT_GREEN}
  230. }
  231.  
  232. procedure spin(sequence shape)
  233. -- spin a 3-D shape around on the screen in interesting ways
  234.     sequence history, coords, overall
  235.     point view_point
  236.     integer spread, r, c
  237.     atom rot_speed
  238.  
  239.     view_point = {6, 8, 7.5} / 2.2
  240.     overall = view(view_point)
  241.     rot_speed = 0.09
  242.     sin_angle = sin(rot_speed)
  243.     cos_angle = cos(rot_speed)
  244.     axis = Z
  245.     history = {}
  246.     spread = 0
  247.     while TRUE do
  248.     coords = new_coords(overall, shape)
  249.     if length(history) > spread then
  250.         display(history[1], coords)
  251.         history = history[2..length(history)]
  252.         if length(history) > spread then
  253.         display(history[1], {})
  254.         history = history[2..length(history)]
  255.         end if
  256.     else
  257.         display({}, coords)
  258.     end if
  259.     history = append(history, coords)
  260.     c = get_key()
  261.     if c != -1 then
  262.         if c = ' ' then
  263.         while TRUE do
  264.             c = get_key()
  265.             if c != -1 and c != ' ' then
  266.             return
  267.             elsif c = ' ' then
  268.             exit
  269.             end if
  270.         end while
  271.         else
  272.         return
  273.         end if
  274.     end if
  275.     r = rand(250)
  276.     if r = 1 then
  277.         axis = X
  278.     elsif r = 2 then
  279.         axis = Y
  280.     elsif r = 3 then
  281.         axis = Z
  282.     elsif r = 4 then
  283.         spread = 5 * rand(25)  -- leave behind many trailing wire images
  284.     elsif r = 5 or r = 6 then
  285.         spread = 0             -- reduce the images back to a sharp picture
  286.     elsif r = 7 then
  287.         if rand(2) = 1 then
  288.         rot_speed = .04
  289.         spread = 0
  290.         else
  291.         rot_speed = .02 * rand(10)
  292.         end if
  293.         sin_angle = sin(rot_speed)
  294.         cos_angle = cos(rot_speed)
  295.     end if
  296.     shape = compute_rotate(axis, shape)
  297.     end while
  298. end procedure
  299.  
  300. -- execution starts here:
  301. if not select_mode(GRAPHICS_MODE) then
  302.     puts(SCREEN, "can't find a good graphics mode\n")
  303. else
  304.     vc = video_config()
  305.     bk_color(7)
  306.     text_color(5)
  307.     clear_screen()
  308.     spin(E)
  309.     bk_color(0)
  310.     if graphics_mode(-1) then
  311.     -- we do this just to ignore the result of graphics_mode(-1)
  312.     end if
  313. end if
  314.  
  315.